package com.palmind.generator;

import com.palmind.parser.mmparser.MMFileTags;
import com.palmind.parser.tags.AbstractTag;
import com.palmind.parser.tags.NodeTag;
import com.palmind.tree.Tree;
import com.palmind.tree.TreeNode;
import com.palmind.util.ArrayList;
import com.palmind.util.StringUtil;

public class MMFileGenerator {

	private static final char QUOTES = '"';
	private static final char SPACE = ' ';
	private static final char EQUAL = '=';
	private static final char LT = '<';
	private static final char SLASH = '/';
	private static final String END = ">\n";
	private static final String COMMOM = "<!-- To view this file, download free mind mapping software FreeMind from http://freemind.sourceforge.net -->\n";

	private StringBuffer stringBuffer = null;

	public String generateMMFile(Tree tree) {
		String content = null;
		stringBuffer = new StringBuffer();
		writeOpenTag(AbstractTag.TAGS[AbstractTag.MAP_TAG]);
		content = tree.getVersion();
		if (content != null)
			writeAttribute("version", content);
		stringBuffer.append(END);
		stringBuffer.append(COMMOM);
		TreeNode root = tree.getRootNode();
		genetateNode(root);
		root = null;
		writeCloseTag(MMFileTags.MAP_TAG);
		return stringBuffer.toString();
	}

	private void genetateNode(TreeNode treeNode) {
		if (treeNode == null)
			return;
		NodeTag node = (NodeTag) treeNode.getBody();
		if (node == null)
			return;
		generateTag(node);
		ArrayList innerTags = node.getInnerTags();
		if (innerTags != null) {
			AbstractTag innerTag = null;
			for (int i = 0; i < innerTags.size(); i++) {
				innerTag = (AbstractTag) innerTags.get(i);
				generateTag(innerTag);
				innerTag = null;
			}
			innerTags = null;
		}
		node = null;

		ArrayList children = treeNode.getChildren();
		if (children != null && children.size() > 0) {
			for (int i = 0; i < children.size(); i++) {
				TreeNode child = (TreeNode) children.get(i);
				genetateNode(child);
				child = null;
			}
		}
		writeCloseTag(AbstractTag.TAGS[AbstractTag.NODE_TAG]);
	}

	private void generateTag(AbstractTag tag) {
		if (tag == null)
			return;
		String tagName = AbstractTag.getTagName(tag.getType());
		if (tagName != null) {
			writeOpenTag(tagName);
			int attr_num = tag.getAttributeValues() == null ? 0 : tag
					.getAttributeValues().length;
			for (int i = 0; i < attr_num; i++)
				if (tag.getAttributeValues()[i] != null)
					writeAttribute(tag.getAttributeNames()[i], tag
							.getAttributeValues()[i]);
			if (tag.getType() == AbstractTag.NODE_TAG)
				stringBuffer.append(END);
			else
				writeCloseTag(null);
		}
	}

	private void writeOpenTag(String tag) {
		stringBuffer.append(LT);
		stringBuffer.append(tag);
	}

	private void writeCloseTag(String tag) {
		if (tag != null) {
			stringBuffer.append(LT);
			stringBuffer.append(SLASH);
			stringBuffer.append(tag);
		} else {
			stringBuffer.append(SLASH);
		}
		stringBuffer.append(END);
	}

	private void writeAttribute(String name, String value) {
		stringBuffer.append(SPACE);
		stringBuffer.append(name);
		stringBuffer.append(EQUAL);
		stringBuffer.append(QUOTES);
		if (name.equals("TEXT"))
			value = StringUtil.string2Code(value);
		stringBuffer.append(value);
		stringBuffer.append(QUOTES);
	}
}
